package com.zerui.manager.app.access;

import com.zerui.basedata.client.PersonnelService;
import com.zerui.basedata.client.dto.PersonnelDTO;
import com.zerui.cola.dto.SingleResponse;
import com.zerui.manager.access.auth.task.domain.AuthTaskDetail;
import com.zerui.manager.access.auth.task.gateway.AuthTaskGateway;
import com.zerui.manager.accessauthorization.gateway.AccessAuthGateWay;
import com.zerui.manager.web.enums.AuthTaskSyncStatusEnum;
import com.zerui.manager.web.enums.DeviceFromEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Collectors;

@Slf4j
@Component
public class AuthTaskManager {

    @Qualifier("taskExecutor")
    @Resource
    private ThreadPoolTaskExecutor taskExecutor;
    @Resource
    private AuthTaskGateway authTaskGateway;
    @Resource
    private AccessAuthGateWay accessAuthGateWay;
    @DubboReference
    private PersonnelService personnelService;

    // 任务队列
    private ConcurrentLinkedQueue<Long> taskQueue = new ConcurrentLinkedQueue<>();

    public void startAuthTask(Long taskId) { // 添加任务ID
        boolean isEmpty = taskQueue.isEmpty();
        taskQueue.offer(taskId);
        if (isEmpty) {
            taskExecutor.execute(() -> {
                while (!taskQueue.isEmpty()) {
                    final Long id = taskQueue.poll();
                    try {
                        authTaskGateway.syncTaskStatus(id, AuthTaskSyncStatusEnum.SYNC_DOING.getCode(), LocalDateTime.now());
                        List<AuthTaskDetail> taskDetailsAll = authTaskGateway.getTaskDetailsByTaskId(id); // 任务详情
                        // 先下发IoT权限
                        List<AuthTaskDetail> iotTaskDetails = taskDetailsAll.stream().filter(c -> c.getDeviceFrom().equals(DeviceFromEnum.FROM_IOT.getCode())).collect(Collectors.toList());
                        for (AuthTaskDetail iot : iotTaskDetails) {
                            String requestId = null;
                            try {
                                authTaskGateway.syncTaskItemStatus(iot.getId(), AuthTaskSyncStatusEnum.SYNC_DOING.getCode(), LocalDateTime.now(), null, null);
                                if (iot.getOperate() == 0) { // 添加
                                    requestId = this.accessAuthGateWay.addIoTAuthority(iot);
                                } else if (iot.getOperate() == 1) { // 删除
                                    requestId = this.accessAuthGateWay.delIoTAuthority(iot);
                                }
                                authTaskGateway.syncTaskItemStatus(iot.getId(), AuthTaskSyncStatusEnum.SYNC_DONE.getCode(), LocalDateTime.now(), null, requestId);
                            } catch (Exception e1) {
                                log.error("向IoT下发门禁授权出错", e1);
                                authTaskGateway.syncTaskItemStatus(iot.getId(), AuthTaskSyncStatusEnum.SYNC_FAILURE.getCode(), LocalDateTime.now(), null, null);
                            }
                        }
                        // 再下发ICC权限
                        List<AuthTaskDetail> iccTaskDetails = taskDetailsAll.stream().filter(c -> c.getDeviceFrom().equals(DeviceFromEnum.FROM_ICC.getCode())).collect(Collectors.toList());
                        for (AuthTaskDetail icc : iccTaskDetails) {
                            try {
                                authTaskGateway.syncTaskItemStatus(icc.getId(), AuthTaskSyncStatusEnum.SYNC_DOING.getCode(), LocalDateTime.now(), null, null);
                                SingleResponse<PersonnelDTO> personRepo = personnelService.getPersonnel(icc.getPersonnelId());
                                PersonnelDTO personDTO = personRepo.getData();
                                if (null == personDTO || StringUtils.isEmpty(personDTO.getNumber())) {
                                    log.warn("向ICC下发门禁授权失败：{}", null == personDTO ? "不存在的人员" : "人员编号不存在");
                                    authTaskGateway.syncTaskItemStatus(icc.getId(), AuthTaskSyncStatusEnum.SYNC_FAILURE.getCode(), LocalDateTime.now(), icc.getRetryTimes() + 1, null);
                                } else if (icc.getOperate() == 0) { // 添加
                                    this.accessAuthGateWay.addICCAuthority(icc, personDTO.getNumber());
                                } else if (icc.getOperate() == 1) { // 删除
                                    this.accessAuthGateWay.delICCAuthority(icc, personDTO.getNumber());
                                }
                                authTaskGateway.syncTaskItemStatus(icc.getId(), AuthTaskSyncStatusEnum.SYNC_DONE.getCode(), LocalDateTime.now(), null, null);
                            } catch (Exception e1) {
                                log.error("向ICC下发门禁授权出错", e1);
                                authTaskGateway.syncTaskItemStatus(icc.getId(), AuthTaskSyncStatusEnum.SYNC_FAILURE.getCode(), LocalDateTime.now(), icc.getRetryTimes(), null);
                            }
                        }
                        authTaskGateway.syncTaskStatus(id, AuthTaskSyncStatusEnum.SYNC_DONE.getCode(), LocalDateTime.now());
                    } catch (Exception e) {
                        authTaskGateway.syncTaskStatus(id, AuthTaskSyncStatusEnum.SYNC_FAILURE.getCode(), LocalDateTime.now());
                    }
                }
            });
        }
    }

}
